package com.brillilab.service.core.account.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.brillilab.common.constant.DateEnum;
import com.brillilab.common.utils.DateUtil;
import com.brillilab.dao.mapper.account.IntegralRecordMapper;
import com.brillilab.domain.enums.account.IntegralStateEnum;
import com.brillilab.domain.enums.account.IntegralTypeEnum;
import com.brillilab.domain.po.account.IntegralRecord;
import com.brillilab.service.core.account.IntegralRecordService;
import com.brillilab.service.core.account.UserAccountService;

/**
 * 用户账户表
 * 
 * @author LJ
 */
@Service
@Transactional
public class IntegralRecordServiceImpl implements IntegralRecordService {

	@Resource
	private IntegralRecordMapper integralRecordMapper;
	@Resource
	private UserAccountService userAccountService;

	@Override
	public IntegralRecord insert(IntegralRecord record) {
		int insert = integralRecordMapper.insert(record);
		Assert.isTrue(insert == 1, "积分记录新增失败");
		return record;
	}

	@Override
	public List<IntegralRecord> getIntegralRecord(Long userId, IntegralStateEnum integralState) {
		LambdaQueryWrapper<IntegralRecord> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(IntegralRecord::getUserId, userId);
		if (integralState != null)
			wrapper.eq(IntegralRecord::getState, integralState.getValue());
		return integralRecordMapper.selectList(wrapper);
	}

	@Override
	public int receivedIntegralBatch(Long userId) {
		int integral = integralRecordMapper.getUnreceivedIntegral(userId);
		if (integral > 0) {
			LambdaQueryWrapper<IntegralRecord> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(IntegralRecord::getUserId, userId);
			wrapper.eq(IntegralRecord::getState, IntegralStateEnum.UNRECEIVED.getValue());
			IntegralRecord record = new IntegralRecord();
			record.setReceiveTime(new Date());
			record.setState(IntegralStateEnum.RECEIVED.getValue());
			int update = integralRecordMapper.update(record, wrapper);
			Assert.isTrue(update >= 1, "积分领取失败");
		}
		return integral;
	}

	@Override
	public int getUnreceivedIntegral(Long userId) {
		return integralRecordMapper.getUnreceivedIntegral(userId);
	}

	@Override
	public void exchangeIntegral(Long userId, Long exchangeId) {
		LambdaQueryWrapper<IntegralRecord> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(IntegralRecord::getUserId, userId);
		wrapper.eq(IntegralRecord::getState, IntegralStateEnum.RECEIVED.getValue());
		IntegralRecord record = new IntegralRecord();
		record.setExchangeId(exchangeId);
		record.setState(IntegralStateEnum.EXCHANGE.getValue());
		int update = integralRecordMapper.update(record, wrapper);
		Assert.isTrue(update >= 1, "积分兑换失败");
	}

	@Override
	public List<IntegralRecord> getIntegralRecordByExchangeId(Long userId, Long exchangeId) {
		LambdaQueryWrapper<IntegralRecord> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(IntegralRecord::getUserId, userId);
		wrapper.eq(IntegralRecord::getExchangeId, exchangeId);
		return integralRecordMapper.selectList(wrapper);
	}

	@Override
	public int receivedIntegral(Long userId, Long recordId) {
		IntegralRecord record = this.getRecord(userId, recordId);
		Assert.notNull(record, "红包不存在");
		// 领取状态：1领取成功，2已过期，3已被领取过
		if (record.getState().equals(IntegralStateEnum.INVALID.getValue())) {
			return 2;
		} else if (record.getState().equals(IntegralStateEnum.RECEIVED.getValue())
				|| record.getState().equals(IntegralStateEnum.EXCHANGE.getValue())) {
			return 3;
		}
		int dateDiff = DateUtil.getDiffDays(record.getCreateTime(), new Date());
		if(dateDiff>0) {
			record.setReceiveTime(new Date());
			record.setState(IntegralStateEnum.INVALID.getValue());
			integralRecordMapper.updateById(record);
			return 2;
		}
		
		record.setReceiveTime(new Date());
		record.setState(IntegralStateEnum.RECEIVED.getValue());
		int update = integralRecordMapper.updateById(record);
		Assert.isTrue(update == 1, "红包领取失败");
		if (record.getIntegral() > 0) {
			userAccountService.addIntegral(userId, record.getIntegral());
		}
		return 1;
	}

	@Override
	public IntegralRecord getRecord(Long userId, Long recordId) {
		LambdaQueryWrapper<IntegralRecord> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(IntegralRecord::getUserId, userId);
		wrapper.eq(IntegralRecord::getId, recordId);
		return integralRecordMapper.selectOne(wrapper);
	}

	@Override
	public List<IntegralRecord> getIntegralRecord(Long userId, IntegralTypeEnum integralType, Date dayBegin,
			Date dayEnd) {
		LambdaQueryWrapper<IntegralRecord> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IntegralRecord::getUserId, userId);
		queryWrapper.eq(IntegralRecord::getType, integralType.getValue());
		queryWrapper.ge(IntegralRecord::getCreateTime, DateUtil.dateString(dayBegin, DateEnum.YYYY_MM_DD_HH_MM_SS.getValue()));
		queryWrapper.le(IntegralRecord::getCreateTime, DateUtil.dateString(dayEnd, DateEnum.YYYY_MM_DD_HH_MM_SS.getValue()));
		return integralRecordMapper.selectList(queryWrapper);
	}

	@Override
	public IntegralRecord getIntegralRecord(Long userId, IntegralTypeEnum integralType, Long dataId) {
		LambdaQueryWrapper<IntegralRecord> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IntegralRecord::getUserId, userId);
		queryWrapper.eq(IntegralRecord::getType, integralType.getValue());
		queryWrapper.eq(IntegralRecord::getDataId, dataId);
		return integralRecordMapper.selectOne(queryWrapper);
	}
	
	@Override
	public List<IntegralRecord> getIntegralRecord(Long userId, IntegralTypeEnum integralType) {
		LambdaQueryWrapper<IntegralRecord> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IntegralRecord::getUserId, userId);
		queryWrapper.eq(IntegralRecord::getType, integralType.getValue());
		return integralRecordMapper.selectList(queryWrapper);
	}

	@Override
	public void setInvalid(List<Long> invalidIds) {
		if(CollectionUtils.isNotEmpty(invalidIds)) {
			IntegralRecord record = new IntegralRecord();
			record.setReceiveTime(new Date());
			record.setState(IntegralStateEnum.INVALID.getValue());
			
			LambdaQueryWrapper<IntegralRecord> updateWrapper = new LambdaQueryWrapper<>();
			updateWrapper.in(IntegralRecord::getId, invalidIds);
			integralRecordMapper.update(record, updateWrapper);
		}
	}


}